﻿using Castle.DynamicProxy;
using Actor.Net.Location;
using System;

namespace Actor.Net
{
    /// <summary>
    /// Actor代理信息
    /// </summary>
    public class ActorProxyInfo
    {
        /// <summary>
        /// Actor源实例
        /// </summary>
        public IActor Actor { get; set; }
        /// <summary>
        /// AOP代理实例
        /// </summary>
        public IActor ActorProxy { get; set; }
        /// <summary>
        /// Actor AOP代理工厂
        /// </summary>
        public ActorProxyFactory Factory { get; set; }
        /// <summary>
        /// 位置服务上下文
        /// </summary>
        public LocationContext LocationContext { get; set; }
    }

    /// <summary>
    /// Actor代理工厂
    /// </summary>
    public class ActorProxyFactory
    {
        /// <summary>
        /// Actor代理创建器
        /// </summary>
        private ProxyGenerator ProxyGenerator { get; } = new ProxyGenerator();

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="type">Actor源实现类型</param>
        /// <param name="interfaceType">Actor源接口类型</param>
        /// <param name="locationContext">Actor源接口类型</param>
        /// <returns>返回Actor代理信息</returns>
        public ActorProxyInfo CreateActorProxy(Type type, Type interfaceType, LocationContext locationContext)
        {
            var proxyInfo = new ActorProxyInfo();
            proxyInfo.Factory = this;
            proxyInfo.LocationContext = locationContext;
            proxyInfo.Actor = (IActor)Activator.CreateInstance(type);
            proxyInfo.Actor.LocationContext = locationContext;
            proxyInfo.Actor.ProxyInfo = proxyInfo;
            var interceptor = new ActorInterceptor();
            proxyInfo.ActorProxy = (IActor)this.ProxyGenerator.CreateInterfaceProxyWithTarget(interfaceType, proxyInfo.Actor, interceptor);
            return proxyInfo;
        }
    }
}
